﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MapData {
   
    public class SimplePolygon {
        
        private List<SimplePoint> points;
        private List<SimplePolygon> innerPoly;


        /// <summary>
        /// pre:
        /// post: Creates a SimplePolygon object
        /// </summary>
        public SimplePolygon(){
            points = new List<SimplePoint>();
        }

        /// <summary>
        /// Pre: A SimplePoint needs to be created and passed to the function
        /// Post: Adds a new simple point to the Polygon.
        /// </summary>
        /// <param name="point"></param>
        public void addPoint(SimplePoint point) {
            points.Add(point);
        }

        /// <summary>
        /// Pre: 
        /// Post: Returns an array of all the points in the Polygon
        /// </summary>
        /// <returns></returns>
        public SimplePoint[] getPoints() {
            return points.ToArray();
        }

        /// <summary>
        /// Pre: 
        /// Post: Returns true if the Polygon has an innerpolygon
        /// </summary>
        /// <returns></returns>
        public bool hasInner() {
            if (innerPoly != null) {
                if (innerPoly.Count > 0) {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Pre: 
        /// Post: Returns the innerPolygons as a SimplePolygon array
        /// </summary>
        /// <returns></returns>
        public SimplePolygon[] getInner() {
            if (innerPoly != null) {
                if (innerPoly.Count > 0) {
                    return innerPoly.ToArray();
                }
            }
            return null;
        }



        /// <summary>
        /// Pre: max > min. All values (value, min, max) are defined
        /// Post: Returns true if value is between min and max
        /// </summary>
        /// <param name="value"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private bool between(double value, double min, double max) { 
            if (((min<value) && (max>=value)) || ((max<value)&&(min>=value))){
                return true;
            }
            return false;
        }

        /// <summary>
        /// Pre: A SimplePoint needs to be created and passed to the function
        /// Post: Returns true if the passed polygon lies within the polygon.	
        /// Adds the polygon to innerPolygon array.
        /// </summary>
        /// <param name="aPoly"></param>
        /// <returns></returns>
        public bool contains(SimplePolygon aPoly) {

            foreach (SimplePoint aPoint in aPoly.getPoints()) {
                bool inner = false;
                for (int i = 0; i < this.points.Count; i++) { 
                    int j = (i+1)%this.points.Count;
                    
                    if (between(aPoint.Y, points[i].Y, points[j].Y)) {
                        if (points[i].X + (aPoint.Y - points[i].Y) / (points[j].Y - points[i].Y) *
                            (points[j].X - points[i].X) < aPoint.X) {
                            inner = !inner;
                        } 
                    }
                }
                if (!inner) {
                    return false;
                }
            } 
            if (innerPoly == null) {
                innerPoly = new List<SimplePolygon>();
            }
            innerPoly.Add(aPoly);
            return true;

        }
    }


}
